package indi.woniu.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.Collection;

/**
 * @Author: GaN601
 * @Date: 2021/12/8 18:55
 * @Description: 认证器
 */
@Configuration
public class CustomAuthenticationProvider implements AuthenticationProvider {
    /**
     * 从数据库查询用户信息
     */
    private UserDetailsService userDetailsService;
    
    @Autowired
    public void setUserDetailsService(final UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
    
    /**
     * 加密器
     */
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    public void setPasswordEncoder(final PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }
    
    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        // 从表单中获取用户名
        String userName = authentication.getName();
        String password = (String) authentication.getCredentials();
        
        UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
        // 加密
        String encodePassword = passwordEncoder.encode(password);
        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
            throw new UsernameNotFoundException("用户名或者密码不正确");
        }
        
        Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
        
        return new UsernamePasswordAuthenticationToken(
                userDetails, encodePassword, authorities);
    }
    
    @Override
    public boolean supports(final Class<?> authentication) {
        return true;
    }
}
